package cn.lg.soar.boot.config;

import cn.lg.soar.common.util.token.SoarJWT;
import cn.lg.soar.core.manager.ITokenStateManager;
import cn.lg.soar.core.manager.PermitLevelManager;
import cn.lg.soar.core.manager.StateTokenManager;
import cn.lg.soar.core.manager.TokenManager;
import cn.lg.soar.core.propertie.security.AccessTokenProperties;
import cn.lg.soar.core.propertie.security.PathPattern;
import cn.lg.soar.core.propertie.security.SecurityProperties;
import cn.lg.soar.mvc.handler.AuthFilter;
import cn.lg.soar.system.api.manager.AuthenticationManager;
import cn.lg.soar.system.api.service.IUserApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.Ordered;

import javax.servlet.Filter;
import java.util.Map;
import java.util.Set;

/**
 * 当前用户过滤器（主要拥于清除当前用户，释放内存）
 * @author luguoxiang
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
@Configuration
public class AuthFilterConfig {

    private final static int LOGIN = 0;
    private final static int ANON = 1;
    private final static int AUTH = 2;
    private final static int AUTH_BY_TYPE_BEGIN = 3;

    @Lazy
    @Autowired
    private SecurityProperties properties;
    @Lazy
    @Autowired
    private AccessTokenProperties accessToken;
    @Lazy
    @Autowired
    private IUserApi userApi;
    @Lazy
    @Autowired
    private AuthenticationManager authenticationManager;
    @Lazy
    @Autowired
    private ITokenStateManager tokenStateManager;

    @Bean
    public FilterRegistrationBean<Filter> authFilterBean() {

        PathPattern pathPattern = properties.getPathPattern();

        // 权限级别管理器
        PermitLevelManager permitLevelManager = new PermitLevelManager();
        permitLevelManager.putLevel(LOGIN, pathPattern.getLogin());
        permitLevelManager.putLevel(ANON, pathPattern.getAnon());
        permitLevelManager.putLevel(AUTH, pathPattern.getAuth());
        // 处理用户类型权限级别
        Map<Byte, Set<String>> authByType = pathPattern.getAuthByType();
        authByType.forEach((k, v) -> {
            permitLevelManager.putLevel(AUTH_BY_TYPE_BEGIN + k, v);
        });

        // 基于redis的有状态token管理器
        TokenManager tokenManager = new StateTokenManager(
                new SoarJWT(accessToken.getSecret(), accessToken.getExpire()),
                tokenStateManager
        );

        // 无状态token管理器
//        this.tokenManager = new TokenManager(new SoarJWT(accessToken.getSecret(), accessToken.getExpire()));

        // 使用内置权限过滤器，可按自己需要实现自己的权限过滤器
        AuthFilter authFilter = new AuthFilter(
                permitLevelManager,
                tokenManager,
                authenticationManager,
                userApi::isSuperAdministrator
        );
        FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
        registration.setFilter(authFilter);
        registration.addUrlPatterns("/*");
        registration.setName("authFilter");
        registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 200);
        return registration;
    }


}
